import type { ReactElement } from 'react';
import React, { useState } from 'react';
import { ColProps, Input } from 'antd';
import { Button, Form, message, Space, Modal, Upload, Collapse } from 'antd';
import { connect, useIntl } from 'umi';
import request from '@/utils/request';
import type { Gutter } from 'antd/lib/grid/row';
import type { FormInstance, FormLayout } from 'antd/lib/form/Form';
import ProTable from '@ant-design/pro-table';
import type { SearchConfig } from '@ant-design/pro-table/lib/components/Form/FormRender';
import type { ConnectState } from '@/models/connect';
import { ExclamationCircleOutlined } from '@ant-design/icons';
import UploadUtil from '@/components/UploadUtil';
import { Scrollbars } from 'react-custom-scrollbars';
import { SizeType } from 'antd/es/config-provider/SizeContext';
// import ActiveReportView from '@/components/ActiveReportView';

const { confirm } = Modal;
const apiURL = '/api/services/app/';
const apiURLReport = '/api/services/app/ERPReports/';
export interface CrudProps {
  new?: string;
  create?: string;
  update?: string;
  get?: string;
  delete?: string;
}
export interface FCProps {
  /** 窗体标题 */
  title?: string | ReactElement;
  /** 回调函数 */
  callback?: (item: any) => void;
  /** 保存前方法 */
  beforeSubmit?: (item: any) => any;
  /** 保存后方法 */
  afterSubmit?: (item: any) => any;
  /** 获取对象前方法 */
  beforeGet?: (item: any) => any;
  /** 获取对象后方法 */
  afterGet?: (item: any) => any;
  /** 新建对象前方法 */
  beforeNewObject?: (item: any) => any;
  /** 表体行双击事件 */
  rowDbClick?: (row: any) => any;
  /** 表体行单击事件 */
  rowClick?: (row: any) => any;
  freshNum?: number;
  record?: any; //
  current?: any;
  /** 间距 */
  gutter: Gutter | [Gutter, Gutter];
  /** 表单排列方式 'horizontal' | 'inline' | 'vertical'*/
  layout: FormLayout;
  /** label 标签布局，同 <Col> 组件，设置 span offset 值，如 {span: 3, offset: 12} 或 sm: {span: 3, offset: 12} */
  labelCol?: ColProps;
  /** 需要为输入控件设置布局样式时，使用该属性，用法同 labelCol */
  wrapperCol?: ColProps;
  /** 是否有边框 */
  bordered?: boolean;
  buttonSize?: SizeType;
  /** 搜索框 */
  search?: false | SearchConfig;
  key?: string;
  /** 表体列表key字段名 */
  rowKey?: string;
  /** 栅格占位格数，为 0 时相当于 display: none */
  span: number;
  /** CRUD方法名，默认 create|update|delete|get*/
  crud?: CrudProps;
  /** 控制器地址 */
  control: string;
  /** 系统报表 */
  sysReportName: string;
  /** 扩展按钮 */
  extraButton?: any;
  /** 自定义窗体 */
  formItem?: React.ReactNode;
  /** 表体查询预设参数 例如：{ PONum: '2001'} */
  params?: any;
  /** 当前用户 */
  currentUser?: any;
  /** 新数据 */
  newData?: any;
  /** 工具栏 ['new', 'save', 'reset', 'delete', 'print', 'export', 'import']*/
  toolbar?: string[];
  /** 滚动X宽度 */
  scrollX?: number;
  /** 滚动Y高度 */
  scrollY?: number;
  /** 表体Table高度，默认320 */
  scrollTableY?: number;
  /** 窗体实体对象 */
  form: FormInstance<any>;
  /** 渲染工具栏，支持返回一个 dom 数组，会自动增加 margin-right */
  toolBarRender?: any;
  /** 是否显示表体 */
  showTable?: boolean;
}
const OperpForm: React.FC<FCProps> = (props: FCProps) => {
  const intl = useIntl();
  const form = props.form;
  const [loading, setLoading] = useState<boolean>(false);
  const [dataSource, setDataSource] = useState<any>([]);
  const [report, setReport] = useState<any>({});
  const [dyColumns, setDyColumns] = useState<any>([]);
  const [record, setRecord] = useState<any>(null);
  const [visiblePrint, setVisiblePrint] = useState<boolean>(false);
  const [selectedRowKeys, setSelectedRowKeys] = useState<any>([]);
  const defaultToolbar = props.toolbar
    ? props.toolbar
    : ['new', 'save', 'reset', 'delete', 'print', 'export', 'import'];
  const runSQL = async (obj: any, params: any = null) => {
    if (!obj || !obj.id) {
      return [];
    }
    let result: any = [];
    setDataSource([]);
    await request(apiURLReport + 'RunSQL', {
      method: 'POST',
      data: { id: obj.id, args: params },
    }).then((response) => {
      if (response) {
        if (response.success) {
          result = response.result;
          setDataSource(response.result);
        }
      }
    });
    return result;
  };
  const onFinish = (values: any) => {
    setLoading(true);
    if (props.beforeSubmit) {
      // eslint-disable-next-line no-param-reassign
      values = props.beforeSubmit(values);
    }
    const act = props.crud?.update ? props.crud?.update : 'Update';
    request(apiURL + props.control + '/' + act, {
      method: act === 'Update' ? 'PUT' : 'POST',
      data: act === 'Modify' ? [values.Model] : values.Model,
    }).then((response) => {
      if (response) {
        if (response.success) {
          message.success(intl.formatMessage({ id: 'save.successful' }));
          let result = response.result;
          if (props.afterSubmit) {
            result = props.afterSubmit(result);
          }
          setRecord(result);
          runSQL(report, props.params);
        }
        setLoading(false);
      }
    });
  };
  const newObject = () => {
    const { currentUser } = props;
    setRecord(null);
    form.resetFields();
    let data = {};
    if (props.beforeNewObject) {
      data = props.beforeNewObject(currentUser);
    }
    request(apiURL + props.control + '/' + (props.crud?.new ? props.crud?.new : 'New'), {
      method: 'POST',
      data,
    }).then((response) => {
      if (response) {
        if (response.success) {
          message.success(intl.formatMessage({ id: 'new.successful' }));
          let Model = response.result.data ? response.result.data : response.result;
          setRecord(Model);
          if (props.afterGet) {
            Model = props.afterGet(Model);
          }
          form.setFieldsValue({ Model });
          runSQL(report, props.params);
        }
        setLoading(false);
      }
    });
  };
  const delObject = () => {
    confirm({
      title: intl.formatMessage({ id: 'warning' }),
      icon: <ExclamationCircleOutlined />,
      content: intl.formatMessage({ id: 'cannot recover after deletion' }),
      onOk() {
        request(
          apiURL + props.control + '/' + (props.crud?.delete ? props.crud?.delete : 'Delete'),
          {
            method: 'DELETE',
            params: { id: record.id },
          },
        ).then((response) => {
          if (response) {
            if (response.success) {
              message.success(intl.formatMessage({ id: 'delete.successful' }));
              setRecord(null);
              form.resetFields();
              runSQL(report, props.params);
            }
          }
        });
      },
    });
  };
  const getObject = (params?: any) => {
    if (props.beforeGet) {
      // eslint-disable-next-line no-param-reassign
      params = props.beforeGet(params);
    }
    if (params) {
      setLoading(true);
      request(apiURL + props.control + '/' + (props.crud?.get ? props.crud?.get : 'Get'), {
        method: 'GET',
        params,
      }).then((response) => {
        if (response) {
          if (response.success) {
            let Model = response.result;
            if (props.afterGet) {
              Model = props.afterGet(response.result);
            }
            form.setFieldsValue({ Model });
            setRecord(Model);
            if (props.callback) {
              props.callback(Model);
            }
          } else {
            message.error(response.statusText);
          }
          setLoading(false);
        }
      });
    }
  };
  // eslint-disable-next-line react-hooks/exhaustive-deps
  const setCurrent = (data?: any) => {
    form.setFieldsValue({ Model: data });
  };
  // eslint-disable-next-line react-hooks/exhaustive-deps
  const getColumns = () => {
    request(apiURLReport + 'GetByName', {
      method: 'GET',
      params: { name: props.sysReportName, rptype: 'SysRpt' },
    }).then((response) => {
      if (response) {
        if (response.success) {
          try {
            const result = response.result;
            setDyColumns(JSON.parse(result.fielDefine));
            setReport(result);
            if (props.params) {
              runSQL(result, props.params);
            }
          } catch {}
        }
      }
    });
  };
  const doPrintView = () => {
    setVisiblePrint(true);
  };
  const handlerImport = (info: any) => {
    if (info.file.status == 'error') {
      setLoading(false);
      console.log(info.file);
      message.error(intl.formatMessage({ id: 'import.error' }));
    }
    if (info.file.status === 'done') {
      message.success(intl.formatMessage({ id: 'import.successful' }));
      setLoading(false);
    } else {
      setLoading(true);
    }
  };
  const handlerExport = async () => {
    setLoading(true);
    try {
      const resp = await request('/api/Excel/Export' + props.control, {
        method: 'POST',
        responseType: 'blob',
      });
      const url = window.URL.createObjectURL(resp);
      const a = document.createElement('a');
      a.href = url;
      a.download = props.control + '.xls';
      a.click();
    } catch (e) {
      message.error(intl.formatMessage({ id: 'export.error' }));
    }
    setLoading(false);
  };
  const resetForm = () => {
    form.resetFields();
    setLoading(false);
    setRecord(null);
  };
  React.useEffect(() => {
    if (dyColumns.length == 0) {
      getColumns();
    }
    if (props.record) {
      setRecord(props.record);
    }
    if (props.current) {
      setCurrent(props.current);
    }
  }, [props.record, dyColumns, props, getColumns, setCurrent]);
  return (
    <div>
      <Form onFinish={onFinish} form={form} layout={props.layout} labelCol={props.labelCol}>
        <Collapse defaultActiveKey={['1', '2']} expandIconPosition="left">
          <Collapse.Panel
            header={props.title}
            key="1"
            extra={[
              <Space
                key="S1"
                onClick={(event) => {
                  event.stopPropagation();
                }}
              >
                <Input.Search placeholder="input search text" style={{ width: 200 }} />
                {defaultToolbar.includes('new') ? (
                  <Button
                    type="primary"
                    loading={loading}
                    onClick={newObject}
                    size={props.buttonSize}
                  >
                    {intl.formatMessage({ id: 'new' })}
                  </Button>
                ) : null}
                {defaultToolbar.includes('save') ? (
                  <Button
                    type="primary"
                    htmlType="submit"
                    loading={loading}
                    disabled={!record}
                    size={props.buttonSize}
                  >
                    {intl.formatMessage({ id: 'save' })}
                  </Button>
                ) : null}
                {defaultToolbar.includes('reset') ? (
                  <Button type="default" onClick={resetForm} size={props.buttonSize}>
                    {intl.formatMessage({ id: 'reset' })}
                  </Button>
                ) : null}
                {defaultToolbar.includes('delete') ? (
                  <Button
                    type="primary"
                    danger
                    onClick={delObject}
                    disabled={!record}
                    size={props.buttonSize}
                  >
                    {intl.formatMessage({ id: 'delete' })}
                  </Button>
                ) : null}
                {defaultToolbar.includes('print') ? (
                  <Button
                    type="dashed"
                    onClick={doPrintView}
                    disabled={!record}
                    size={props.buttonSize}
                  >
                    {intl.formatMessage({ id: 'print' })}
                  </Button>
                ) : null}
                {defaultToolbar.includes('import') ? (
                  <Upload
                    accept=".xls,.xlsx,application/vnd.ms-excel"
                    name="file"
                    action={'/api/Excel/Import' + props.control}
                    headers={{
                      Authorization: UploadUtil.accessToken,
                    }}
                    beforeUpload={UploadUtil.checkExcel}
                    showUploadList={false}
                    onChange={handlerImport}
                  >
                    <Button loading={loading} size={props.buttonSize}>
                      {intl.formatMessage({ id: 'import' })}
                    </Button>
                  </Upload>
                ) : null}
                {defaultToolbar.includes('export') ? (
                  <Button
                    type="default"
                    onClick={handlerExport}
                    loading={loading}
                    size={props.buttonSize}
                  >
                    {intl.formatMessage({ id: 'export' })}
                  </Button>
                ) : null}
                {props.extraButton}
              </Space>,
            ]}
          >
            <Scrollbars autoHide={false} style={{ height: props.scrollY ? props.scrollY : 200 }}>
              <div style={{ width: '100%', overflowX: 'hidden' }}>{props.formItem}</div>
            </Scrollbars>
          </Collapse.Panel>
        </Collapse>
      </Form>
      <Scrollbars
        hidden={props.showTable}
        autoHide={false}
        style={{ height: props.scrollTableY ? props.scrollTableY : 320 }}
      >
        <ProTable
          columns={dyColumns}
          dataSource={dataSource}
          rowKey={props.rowKey ? props.rowKey : 'Id'}
          bordered={props.bordered}
          search={props.search}
          defaultSize="small"
          request={async (params = {}, sort, filter) => {
            console.log(sort, filter);
            return runSQL(report, params);
          }}
          rowSelection={{
            selectedRowKeys,
            onChange: setSelectedRowKeys,
          }}
          toolBarRender={props.toolBarRender}
          onRow={(e) => {
            return {
              onClick: () => {
                if (props.rowClick) {
                  props.rowClick(e);
                }
              },
              onDoubleClick: () => {
                if (props.rowDbClick) {
                  props.rowDbClick(e);
                } else {
                  getObject({ id: e.Id });
                }
              },
            };
          }}
        />
      </Scrollbars>
      <Modal
        width={1000}
        title={intl.formatMessage({ id: 'print' })}
        visible={visiblePrint}
        destroyOnClose={true}
        onCancel={() => setVisiblePrint(false)}
        footer={false}
      >
        {/* <ActiveReportView zoom="FitPage" availableExports={['pdf']} /> */}
      </Modal>
    </div>
  );
};

export default connect(({ user }: ConnectState) => ({
  currentUser: user.currentUser,
}))(OperpForm);
